namespace("lesp.songfacts");

/**
 * Songfacts' song page. Retrives facts and comments.
 */
lesp.songfacts.Song = lesp.abstract.Song.extend({

  _baseUrl  : "http://www.songfacts.com",


  getFacts : function()
  {
    if(!this._document)
    {
      throw new Error("Song document is not yet ready");
    }

    return this._document.find("ul.factsullist-sf li div.inner").map(function()
    {
      return jQuery(this).html();
    }).get(); 
  },
  
  getComments : function()
  {
    if(!this._document)
    {
      throw new Error("Song document is not yet ready");
    }

    return this._document.find("div.sfdetail-comments .comment-holder").map(function()
    {
      return jQuery(this).html();
    }).get();
  }

});

/**
 * Songfacts' manager. Searches for a song of given artist.
 */
lesp.songfacts.Manager = lesp.abstract.Manager.extend({

  _searchUrlTemplate : "http://www.songfacts.com/search-artist-1.php?{0}",
  _baseUrl           : "http://www.songfacts.com",  


  _onLoad : function(response)
  {
    var contents = jQuery(lesp.mangleHtml(response.responseText));
    var artist   = contents.find(".search-holder ul.songullist-blue li a:eq(0)");

    if(artist.length)
    {
      var url = artist.attr("href");
      if(url.indexOf(this._baseUrl) != 0)
      {
        url = this._baseUrl + url;
      }
      
      GM_xmlhttpRequest({
        method  : "get",
        url     : url,
        onload  : this._onArtistSongsLoad.bind(this),
        onerror : this.notify.bind(this, "failed")
      });
    }
    else
    {
      this.notify("failed");
    }
  },
  
  _onArtistSongsLoad : function(response)
  {
    var contents = jQuery(lesp.mangleHtml(response.responseText));
    
    if(response.finalUrl.indexOf(this._searchUrlTemplate.format("")) == 0)
    {
      this.notify("failed");
    }
    else
    {
      var track      = this._track.toLowerCase();
      var candidates = contents.find("ul.songullist-orange li a")
        .map(function()
        {
          var item     = jQuery(this);
          var distance = item.text().toLowerCase().distance(track);
          
          // jQuery filters nulls and concats returned arrays
          return distance < 8 ? {dist : distance, href : item.attr("href"), name : item.text()} : null;  
        })
        .get()
        .sort(function(a, b)
        {
          return a.dist - b.dist;
        });
      
      if(candidates.length)
      {
        this._songUrlQuery = candidates[0].href;

        var song = new lesp.songfacts.Song(candidates[0]);
        song.attach("loaded",    this.notify.bind(this, "loaded", song));
        song.attach("notLoaded", this.notify.bind(this, "failed"));

        this.notify("found");
      }
      else
      {
        this.notify("failed");
      }
    }
  }

});

/**
 * Songfacts' song renderer. Creates ready DOM node of facts and comment.
 */
lesp.songfacts.Renderer = lesp.abstract.Renderer.extend({

  _title : "SongFacts",


  _createFacts : function()
  {
    var facts = this._song.getFacts().map(function(fact)
    {
      return "<li>{0}</li>".format(fact);
    }).join("");
    
    return facts 
      ? [
        "<h4>Facts</h4>",
        "<ul class='journalsSmall' style='font-size:12px;'>",
        facts,
        "</ul>"
      ].join("")
      : "";
  },

  _createMenu : function()
  {
    var comments = this._song.getComments().length;
    var pageUrl  = this._song.getPageUrl();
    var result   = jQuery("<div style='text-align: right; padding: 5px 10px 10px 0; font-size: 11px;'/>")
      .append(comments ? "<a href='#songfacts-commnets' class='info show-comments'>Show comments</a>" : "")
      .append(comments ? "<span style='padding-left: 10px;'/>" : "")
      .append("<a href='{0}' class='info' target='_blank'>SongFacts page</a>".format(pageUrl));

    result.find("a.show-comments").click(function()
    {
      var anchor = jQuery(this);

      anchor.parent()
        .next().toggle()
        .next().toggle();

      anchor.text(anchor.data("shown") ? "Show comments" : "Hide comments");
      anchor.data("shown", !anchor.data("shown"));
    });

    return result;
  },

  _createComments : function()
  {
    var comments = this._song.getComments().map(function(comment)
    {
      comment = jQuery("<div>{0}</div>".format(comment))
        .find("span:eq(1)").css("color", "#696969").prepend("<br/>").parent()
        .html();
        
      return "<li>{0}</li>".format(comment);
    }).join("");
    
    return comments 
      ? [
        "<h4 id='songfacts-commnets' style='display:none;'>Comments</h4>",
        "<ul class='journalsSmall' style='display:none; overflow:auto; height:450px; font-size:12px;'>",
        comments,
        "</ul>"
      ].join("") 
      : "";
  },

  render : function()
  {
    return jQuery("<div/>")
      .append(this._createMatchNotice())
      .append(this._createFacts())
      .append(this._createMenu())
      .append(this._createComments());
  }

});


